Skip to content

fix(plugins): qualify browse and filter queries with the table schema#1758

Merged
datlechin merged 2 commits into
mainfrom
fix/mssql-oracle-schema-qualified-browse
Jun 23, 2026
Merged

fix(plugins): qualify browse and filter queries with the table schema#1758
datlechin merged 2 commits into
mainfrom
fix/mssql-oracle-schema-qualified-browse

Conversation

@datlechin

@datlechin datlechin commented Jun 23, 2026

Copy link
Copy Markdown
Member

Problem

Opening data for a SQL Server table or view outside the dbo schema failed with "Invalid object name 'X'" (#1754). Structure and View definition worked; only data browsing failed.

Root cause

PluginDatabaseDriver has schema-less and schema:-bearing overloads of buildBrowseQuery/buildFilteredQuery. The app calls the schema: overload with the correct schema, but PluginKit's default for that overload silently drops the schema and delegates to the schema-less one. MSSQL and Oracle implemented only the schema-less overload, so the schema never reached the FROM clause. MySQL/PostgreSQL avoid this by returning nil, which makes the app's TableQueryBuilder qualify the table itself.

Fix

Read path (the reported bug):

  • MSSQLSchemaQueries (TableProMSSQLCore): pure, tested qualifiedName/browse/filtered builders that own schema qualification, reusing the existing bracketed helper.
  • MSSQL and Oracle plugins implement the schema: overloads of buildBrowseQuery/buildFilteredQuery, qualifying the FROM target ([schema].[table] / "SCHEMA"."TABLE"). The schema-less overloads delegate with schema: nil, keeping the registration probe working.

Write path (found in review, same root cause):
Before this, editing and saving a non-default-schema table generated UPDATE [table] with no schema, which resolved against the login default schema (error, or a silent write to the wrong table). The read fix made those tables browsable and therefore editable, so this had to ship together.

  • New additive generateStatements(table:schema:...) protocol overload (default delegates to the schema-less one).
  • MSSQL and Oracle qualify their INSERT/UPDATE/DELETE targets with the table schema.
  • DataChangeManager carries the tab's schema and passes it through; the three table-context call sites supply tableContext.schemaName.

FK navigation (found in review):

  • MainContentCoordinator+FKNavigation used fkInfo.referencedSchema for the first FK-filtered load while the tab metadata and later pages used the resolved targetSchema, so the first query could be unqualified and later pages could swap to a different table. Now uses targetSchema consistently.

ABI

The new generateStatements(table:schema:...) requirement has a default implementation, so this is additive and binary-compatible (no currentPluginKitVersion bump), same pattern as the existing buildBrowseQuery(table:schema:) overload. scripts/check-pluginkit-abi.sh shows only the added requirement. Labeled abi-additive.

Tests

TableProMSSQLCoreTests: 6 new cases for schema-qualified vs unqualified browse/filter output (24 pass). The DML generators are private plugin methods that aren't reachable from the test target; their qualification routes through the unit-tested MSSQLSchemaQueries.qualifiedName.

Shipping

MSSQL and Oracle are registry-only plugins, so this reaches users only after re-releasing both plugins.

Follow-ups (pre-existing, not worsened by this PR)

  • MSSQL/Oracle FK introspection never selects the referenced owner/schema, so referencedSchema is always nil and cross-schema FK following still can't qualify perfectly.
  • Export (ExportDataSourceAdapter) qualifies the FROM target with the database name, conflating database vs schema.

Fixes #1754

https://claude.ai/code/session_0198faM6VCrViRU4XwRoS1DC

@datlechin datlechin added the abi-additive PluginKit ABI diff reviewed as additive; no version bump needed label Jun 23, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5bda130dbd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

func fetchFilteredRowCount(table: String, filters: [(column: String, op: String, value: String)], logicMode: String) async throws -> Int?
// Statement generation (optional, for NoSQL plugins)
func generateStatements(table: String, columns: [String], primaryKeyColumns: [String], changes: [PluginRowChange], insertedRowData: [Int: [PluginCellValue]], deletedRowIndices: Set<Int>, insertedRowIndices: Set<Int>) -> [(statement: String, parameters: [PluginCellValue])]?
func generateStatements(table: String, schema: String?, columns: [String], primaryKeyColumns: [String], changes: [PluginRowChange], insertedRowData: [Int: [PluginCellValue]], deletedRowIndices: Set<Int>, insertedRowIndices: Set<Int>) -> [(statement: String, parameters: [PluginCellValue])]?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Bump PluginKit ABI for the new protocol requirement

Adding this method to the public PluginDatabaseDriver protocol changes the protocol witness table. A driver bundle compiled against the previous PluginKit v18 cannot provide this witness, but PluginManager.currentPluginKitVersion/minimumCompatiblePluginKitVersion still accept v18 bundles, and DataChangeManager.generateSQL now calls this overload through any PluginDatabaseDriver; user-installed drivers built before this change can therefore pass validation and fail at runtime. Please bump the PluginKit version/min compatibility (and plugin Info.plists) or avoid changing the protocol ABI.

Useful? React with 👍 / 👎.

@datlechin datlechin merged commit d285da4 into main Jun 23, 2026
3 of 4 checks passed
@datlechin datlechin deleted the fix/mssql-oracle-schema-qualified-browse branch June 23, 2026 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

abi-additive PluginKit ABI diff reviewed as additive; no version bump needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Opening Table or View not in DBO schema gives error.

1 participant